package com.by.toolkitspring.dubbo.filter;

import com.by.toolkit.enums.ErrorCodeEnum;
import com.by.toolkit.exceptions.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.filter.ExceptionFilter;
import org.apache.dubbo.rpc.service.GenericService;

import static com.by.toolkit.utils.ExceptionUtil.getStackTrace;

/**
 * @author Tian Wei
 * @version 1.0
 * @date 2023/12/27 6:08 PM
 */
@Slf4j
@Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER})
public class ByDubboExceptionFilter extends ExceptionFilter {

    @Override
    public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
        //invoke之后会继续执行,这块需要再次拦截
        if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
            Throwable exception = appResponse.getException();
            if (exception instanceof ServiceException) {
                log.warn("[ByDubboExceptionFilter][onResponse] ServiceException:[{}]", getStackTrace(exception));
                appResponse.setException(exception);
                return;
            } else if (exception instanceof RpcException) {
                RpcException rpcException = (RpcException) exception;
                if (rpcException.isTimeout()) {
                    log.warn("[ByDubboExceptionFilter][onResponse] rpcTimeOut RpcException:[{}]", getStackTrace(exception));
                } else {
                    log.error("[ByDubboExceptionFilter][onResponse] RpcException:[{}]", getStackTrace(exception));
                }
                appResponse.setException(new ServiceException(ErrorCodeEnum.ILLEGAL_SERVICE_EXCEPTION.getErrorCode()));
                return;
            } else if (exception instanceof RuntimeException) {
                log.error("[ByDubboExceptionFilter][onResponse] RuntimeException:[{}]", getStackTrace(exception));
                appResponse.setException(new ServiceException(ErrorCodeEnum.ILLEGAL_SERVICE_EXCEPTION.getErrorCode()));
                return;
            } else {
                log.error("[ByDubboExceptionFilter][onResponse] 非运行时异常,错误原因为:{}", getStackTrace(exception));
            }
        }

        super.onResponse(appResponse, invoker, invocation);
    }

    @Override
    public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) {
    }


}
